#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/objects.h>

void P_ARR(unsigned char *arr, int size) {
  printf("[");
  for (int i = 0; i < size; i++) {
    if (arr[i] > 127) {
      printf("%d", arr[i] - 256);
    } else {
      printf("%d", arr[i]);
    }
    if (i < size - 1) {
      printf(", ");
    }
  }
  printf("]\n");
}

void P_CURVE(const EC_GROUP *EG) {
   int nid = EC_GROUP_get_curve_name(EG);
   if (nid != NID_undef) {
      printf("%s\n", OBJ_nid2sn(nid));
   }
}

int main() {
  EC_GROUP *EG;
  EC_POINT *EP;
  EC_KEY *EK;
  int STATE[] = {0, 0, 0, 0};
  int S1 = 24, S2 = 49, S3 = 133;
  unsigned char SK[S1], CK[S2];
  unsigned char DER[] = {
    48, -127, -126, 2, 1, 1, 48, 36, 6, 7, 42, -122, 72, -50, 61, 1, 1, 2, 25, 0,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2,
    -1, -1, -18, 55, 48, 6, 4, 1, 0, 4, 1, 3, 4, 49, 4, -37, 79, -15, 14, -64, 87,
    -23, -82, 38, -80, 125, 2, -128, -73, -12, 52, 29, -91, -47, -79, -22, -32, 108,
    125, -101, 47, 47, 109, -100, 86, 40, -89, -124, 65, 99, -48, 21, -66, -122, 52,
    64, -126, -86, -120, -39, 94, 47, -99, 2, 25, 0, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -2, 38, -14, -4, 23, 15, 105, 70, 106, 116, -34, -3, -115, 2, 1, 1
  };
  unsigned char S_PK[] = {
    4, -59, 23, 69, 30, 95, 105, 75, 121, -35, -97, -23, -51, -76, -108, 121, 34, 87,
    -20, -31, -125, 17, 35, 64, -126, -12, 64, -44, -79, 51, -93, -38, 116, -119, -80,
    82, 88, 5, 2, -13, 70, 77, 28, -1, -115, 28, 101, -85, -8
  };
  const unsigned char *REF = DER;
  EG = d2i_ECPKParameters(NULL, &REF, S3);
  P_CURVE(EG);
  EP = EC_POINT_new(EG);
  STATE[0] = EC_POINT_oct2point(EG, EP, S_PK, S2, NULL);
  if (STATE[0]) {
    EK = EC_KEY_new();
    STATE[1] = EC_KEY_set_group(EK, EG);
    if (STATE[1]) {
      STATE[2] = EC_KEY_generate_key(EK);
      if (STATE[2]) {
        ECDH_compute_key(SK, S1, EP, EK, NULL);
        EC_POINT_point2oct(EG, EC_KEY_get0_public_key(EK), 4, CK, S2, 0);
        P_ARR(SK, S1);
        P_ARR(CK, S2);
        STATE[3] = EC_KEY_check_key(EK);
        if (STATE[3]) {
          printf("STATUS: Y\n");
        } else {
          printf("STATUS: N\n");
        }
      }
    }
  }
  EC_POINT_clear_free(EP);
  EC_GROUP_free(EG);
  EC_KEY_free(EK);
  return 0;
}
